/*
 * Copyright 2012 ITC Tsinghua University. All Rights Reserved.
 */
package cn.edu.tsinghua.cic.ccss.bo.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;

import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.log4j.Logger;
import org.forten.core.dao.rdb.hibernate.HibernateDao;
import org.forten.core.dao.rdb.hibernate.QueryInfo;
import org.forten.core.dao.rdb.query.hql.order.Order;
import org.forten.core.dao.rdb.query.hql.statement.OrderBy;
import org.forten.core.dao.rdb.query.hql.statement.Select;
import org.forten.core.dao.rdb.query.parameter.Param;
import org.forten.core.dao.rdb.query.parameter.Type;
import org.forten.core.qo.QueryField.MatchType;
import org.forten.core.qo.QueryObject;
import org.forten.core.qo.QueryObjectHelper;
import org.forten.core.ro.DtoResultWithPageInfo;
import org.forten.core.ro.PageInfo;
import org.forten.mail.template.FreeMarkerBean;
import org.forten.utils.collection.ArrayUtil;
import org.forten.utils.collection.CollectionUtil;
import org.forten.utils.common.DateUtil;
import org.forten.utils.common.NumberUtil;
import org.forten.utils.common.StringUtil;
import org.forten.utils.security.TripletsDESUtil;
import org.forten.utils.system.BeanPropertyUtil;
import org.forten.utils.system.LogUtil;
import org.forten.utils.system.PropertiesFileReader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.thcic.sms.client.SmsClient;

import cn.edu.tsinghua.cic.ccss.bo.CourseBo;
import cn.edu.tsinghua.cic.ccss.bo.SystemSettingBo;
import cn.edu.tsinghua.cic.ccss.dto.CourseDto;
import cn.edu.tsinghua.cic.ccss.dto.CourseDto4Export;
import cn.edu.tsinghua.cic.ccss.dto.CourseDto4Import;
import cn.edu.tsinghua.cic.ccss.dto.CourseDto4Save;
import cn.edu.tsinghua.cic.ccss.dto.SendMessageToCadreDto;
import cn.edu.tsinghua.cic.ccss.entity.Course;
import cn.edu.tsinghua.cic.ccss.entity.MsgResultOfChekIn;
import cn.edu.tsinghua.cic.ccss.qo.CourseQo;

/**
 * 
 * 
 * @author <a href="mailto:du_yi@bbn.cn">Duyi</a>
 * 
 * @since 2012-5-10
 */
@Service("courseBo")
public class CourseBoImpl implements CourseBo {
	private static Logger log = Logger.getLogger(CourseBoImpl.class);

	@Resource
	private HibernateDao hibernateDao;
	/*
	 * @Resource private CourseDaoImpl courseDao;
	 */
	@Resource(name = "systemSettingBo")
	private SystemSettingBo systemSettingBo;
	@Resource
	private FreeMarkerBean freeMarkerBean;

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.edu.tsinghua.cic.ccss.bo.CourseBo#loadCourseDto(java.lang.Long)
	 */
	@Override
	@Transactional
	public CourseDto loadCourseDto(Long id) {
		CourseDto dto = new CourseDto();
		Course entity = hibernateDao.load(Course.class, id);
		BeanPropertyUtil.copy(dto, entity);
		return dto;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.edu.tsinghua.cic.ccss.bo.CourseBo#doSave(cn.edu.tsinghua.cic.ccss.
	 * dto.CourseDto)
	 */
	@Override
	@Transactional
	public Long doSave(CourseDto4Save dto) {
		Course entity = new Course();
		BeanPropertyUtil.copy(entity, dto);
		entity.setNum(getCourseNum());
		// 计算选课结束时间
		Date teachTime = entity.getTeachTime();
		Date finalEndDate = getEndChooseTime(teachTime);
		entity.setEndTimeChoose(finalEndDate);

		return hibernateDao.save(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.edu.tsinghua.cic.ccss.bo.CourseBo#doUpdate(cn.edu.tsinghua.cic.ccss
	 * .dto.CourseDto)
	 */
	@Override
	@Transactional
	public void doUpdate(CourseDto dto) {
		Course entity = this.hibernateDao.load(Course.class, dto.getId());
		BeanPropertyUtil.copy(entity, dto);
		hibernateDao.update(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.edu.tsinghua.cic.ccss.bo.CourseBo#doBatchImport(java.util.List)
	 */
	@Override
	@Transactional
	public List<String> doBatchImport(List<CourseDto4Import> dtoList) {
		List<String> formatErrMsg = new ArrayList<String>();
		if (CollectionUtil.isEmpty(dtoList)) {
			formatErrMsg.add("导入数据为空");
			return formatErrMsg;
		}
		Course[] arr = new Course[dtoList.size()];
		long courseNum = NumberUtil.parseNumber(getCourseNum(), Long.class);
		LogUtil.info(log, "于%s准备导入课程信息数据",
				DateUtil.convertDateToString(new Date()));
		int i = 0;
		for (CourseDto4Import dto : dtoList) {
			String errMsg = getFormatErrorMsg(dto);
			if (StringUtil.hasText(errMsg)) {
				formatErrMsg.add("第" + (i + 2) + "行数据格式错误：" + errMsg);
				i++;
				continue;
			}
			Course entity = new Course();
			BeanPropertyUtil.copy(entity, dto);
			entity.setNum(Long.toString(courseNum));

			// 计算选课结束时间
			Date teachTime = entity.getTeachTime();
			Date finalEndDate = getEndChooseTime(teachTime);
			entity.setEndTimeChoose(finalEndDate);

			arr[i] = entity;
			courseNum++;
			i++;
		}
		if (!CollectionUtil.isEmpty(formatErrMsg)) {
			return formatErrMsg;
		}
		LogUtil.info(log, "于%s完成课程信息数据导入，共导入%d条数据",
				DateUtil.convertDateToString(new Date()), i);
		hibernateDao.save(arr);
		return formatErrMsg;
	}

	private Date getEndChooseTime(Date teachTime) {

		String teachDay = DateUtil.convertDateToString(teachTime,
				DateUtil.DATETIME_PATTERN);
		Date teachDate = DateUtil.convertStringToDate(teachDay,
				DateUtil.DATETIME_PATTERN);
		int dateInterval = systemSettingBo
				.getIntValue("SELECT_COURSE_END_DATE");
		Date endDate = DateUtil.calculateDate(teachDate, 0 - dateInterval,
				Calendar.DAY_OF_MONTH);
		Calendar cal = Calendar.getInstance();
		cal.setTime(endDate);

		@SuppressWarnings("deprecation")
		Date finalEndDate = DateUtil.getCommonTime(cal.get(Calendar.YEAR),
				cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE),
				endDate.getHours(), endDate.getMinutes(), endDate.getSeconds());
		return finalEndDate;
	}

	private String getFormatErrorMsg(CourseDto4Import dto) {
		StringBuilder sb = new StringBuilder();
		if (!StringUtil.hasText(dto.getName())) {
			sb.append("[课程名不可为空]");
		}
		if (!StringUtil.hasText(dto.getClassroom())) {
			sb.append("[上课地点不可为空]");
		}
		if (!StringUtil.hasText(dto.getTeacherName())) {
			sb.append("[任课老师不可为空]");
		}
		if (dto.getClassCapacity() <= 0) {
			sb.append("[课容量必须大于0]");
		}
		if (dto.getCredit() <= 0) {
			sb.append("[学时必须大于0]");
		}
		if (dto.getTeachTime().before(new Date())) {
			sb.append("[授课时间必须晚于当前时间]");
		}
		return sb.toString();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.edu.tsinghua.cic.ccss.bo.CourseBo#queryCourseDtoPage(cn.edu.tsinghua
	 * .cic.ccss.qo.CourseQo, int)
	 */
	/*
	 * @Override
	 * 
	 * @Transactional(readOnly = true) public DtoResultWithPageInfo<CourseDto>
	 * queryCourseDtoPage(CourseQo qo, int page,String fieldName,boolean isAsc)
	 * { QueryInfo qi = QueryObjectHelper.buildQueryInfo(qo);
	 * qi.setSelect(Select.getCountSelect("id")); Long totalEntities =
	 * hibernateDao.getCount(qi); if (totalEntities == 0) { return new
	 * DtoResultWithPageInfo<CourseDto>( new ArrayList<CourseDto>(), null); }
	 * 
	 * PageInfo pi = PageInfo .getInstance(page,
	 * systemSettingBo.getIntValue("DEFAULT_PAGE_SIZE"), totalEntities);
	 * if(isAsc){ qi.setOrderby(OrderBy.getOrderBy(Order.asc(fieldName))); }
	 * else { qi.setOrderby(OrderBy.getOrderBy(Order.desc(fieldName))); }
	 * qi.setFirstResult(pi.getFirstResultNum());
	 * qi.setMaxResult(pi.getPageSize()); qi.setPage(true); qi.setSelect(null);
	 * qi.setUseCache(true);
	 * 
	 * List<Course> result = hibernateDao.findEntities(qi); List<CourseDto>
	 * dtoResult = new ArrayList<CourseDto>(result.size()); for (Course entity :
	 * result) { CourseDto courseDto = new CourseDto();
	 * BeanPropertyUtil.copy(courseDto, entity); dtoResult.add(courseDto); }
	 * return new DtoResultWithPageInfo<CourseDto>(dtoResult, pi); }
	 */

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.edu.tsinghua.cic.ccss.bo.CourseBo#queryCourseDto4Selection(cn.edu.
	 * tsinghua.cic.ccss.qo.CourseQo4Selection)
	 */
	/*
	 * @Transactional public DtoResultWithPageInfo<CourseDto>
	 * queryCourseDto4Selection( CourseQo4Selection qo, int pageNo,String type)
	 * { List<Course> result = null; long total = 0; String hql = null;
	 * if("user".equals(type)){ hql =
	 * "FROM Course WHERE to_date(:currTime,'yyyy/MM/dd HH24:MI') BETWEEN startTimeChoose AND endTimeChoose "
	 * ; } else { hql =
	 * "FROM Course WHERE to_date(:currTime,'yyyy/MM/dd HH24:MI') BETWEEN startTimeChoose AND teachTime "
	 * ; } String currTime = DateUtil.convertDateToString(new Date(),
	 * "yyyy/MM/dd HH:mm"); String countHql = "SELECT count(id) " + hql; if
	 * (StringUtil.hasText(qo.getName())) { countHql = countHql +
	 * "AND name LIKE :name "; hql = hql + "AND name LIKE :name "; } if
	 * (StringUtil.hasText(qo.getTeacherName())) { countHql = countHql +
	 * "AND teacherName LIKE :teacherName "; hql = hql +
	 * "AND teacherName LIKE :teacherName "; } //时间段起始、终止查询时间不为空
	 * if(StringUtil.hasText(qo.getStart()) && StringUtil.hasText(qo.getEnd())){
	 * countHql = countHql +
	 * "AND teachTime BETWEEN to_date(:start,'yyyy/MM/dd HH24:MI') AND to_date(:end,'yyyy/MM/dd HH24:MI')"
	 * ; hql = hql +
	 * "AND teachTime BETWEEN to_date(:start,'yyyy/MM/dd HH24:MI') AND to_date(:end,'yyyy/MM/dd HH24:MI')"
	 * ; } //起始时间不为空格，终止时间为空 if(StringUtil.hasText(qo.getStart()) &&
	 * !StringUtil.hasLength(qo.getEnd())){ //
	 * qo.setEnd(currTime);终止时间为空，默认为系统当前时间 countHql = countHql +
	 * "AND teachTime BETWEEN to_date(:start,'yyyy/MM/dd HH24:MI') AND to_date(:end,'yyyy/MM/dd HH24:MI')"
	 * ; hql = hql +
	 * "AND teachTime BETWEEN to_date(:start,'yyyy/MM/dd HH24:MI') AND to_date(:currTime,'yyyy/MM/dd HH24:MI')"
	 * ; } hql = hql + "ORDER BY teachTime"; //This time we need more conditions
	 * to judge for four arguments if (StringUtil.hasText(qo.getName()) &&
	 * !StringUtil.hasText(qo.getTeacherName()) &&
	 * !StringUtil.hasText(qo.getStart())) { total =
	 * courseDao.getCount(countHql, Param.getCommonParam("currTime", currTime,
	 * Type.STRING), Param.getDefaultVarcharParamForLike("name", qo.getName()));
	 * } else if (!StringUtil.hasText(qo.getName()) &&
	 * StringUtil.hasText(qo.getTeacherName()) &&
	 * !StringUtil.hasText(qo.getStart())) { total = courseDao.getCount(
	 * countHql, Param.getCommonParam("currTime", currTime, Type.STRING),
	 * Param.getDefaultVarcharParamForLike("teacherName", qo.getTeacherName()));
	 * } else if (StringUtil.hasText(qo.getName()) &&
	 * StringUtil.hasText(qo.getTeacherName()) &&
	 * !StringUtil.hasText(qo.getStart())) { total = courseDao.getCount(
	 * countHql, Param.getCommonParam("currTime", currTime, Type.STRING),
	 * Param.getDefaultVarcharParamForLike("name", qo.getName()),
	 * Param.getDefaultVarcharParamForLike("teacherName", qo.getTeacherName()));
	 * } else if(StringUtil.hasText(qo.getName()) &&
	 * StringUtil.hasText(qo.getTeacherName()) &&
	 * StringUtil.hasText(qo.getStart()) && StringUtil.hasText(qo.getEnd()) ){
	 * total = courseDao.getCount( countHql, Param.getCommonParam("currTime",
	 * currTime, Type.STRING), Param.getDefaultVarcharParamForLike("name",
	 * qo.getName()), Param.getDefaultVarcharParamForLike("teacherName",
	 * qo.getTeacherName()), Param.getCommonParam("start", qo.getStart(),
	 * Type.STRING), Param.getCommonParam("end", qo.getEnd(), Type.STRING)); }
	 * else if(StringUtil.hasText(qo.getName()) &&
	 * StringUtil.hasText(qo.getTeacherName()) &&
	 * !StringUtil.hasText(qo.getStart()) && StringUtil.hasText(qo.getEnd()) ){
	 * total = courseDao.getCount( countHql, Param.getCommonParam("currTime",
	 * currTime, Type.STRING), Param.getDefaultVarcharParamForLike("name",
	 * qo.getName()), Param.getDefaultVarcharParamForLike("teacherName",
	 * qo.getTeacherName()), Param.getCommonParam("start", qo.getStart(),
	 * Type.STRING), Param.getCommonParam("end", currTime, Type.STRING)); } else
	 * if(!StringUtil.hasText(qo.getName()) &&
	 * !StringUtil.hasText(qo.getTeacherName()) &&
	 * StringUtil.hasText(qo.getStart()) && !StringUtil.hasText(qo.getEnd())){
	 * total = courseDao.getCount(countHql, Param.getCommonParam("currTime",
	 * currTime, Type.STRING), Param.getCommonParam("start", qo.getStart(),
	 * Type.STRING), Param.getCommonParam("end", currTime, Type.STRING)); } else
	 * if(!StringUtil.hasText(qo.getName()) &&
	 * !StringUtil.hasText(qo.getTeacherName()) &&
	 * StringUtil.hasText(qo.getStart()) && StringUtil.hasText(qo.getEnd())){
	 * total = courseDao.getCount(countHql, Param.getCommonParam("currTime",
	 * currTime, Type.STRING), Param.getCommonParam("start", qo.getStart(),
	 * Type.STRING), Param.getCommonParam("end", qo.getEnd(), Type.STRING)); }
	 * else {
	 * 
	 * total = courseDao.getCount(countHql, Param.getCommonParam("currTime",
	 * currTime, Type.STRING)); }
	 * 
	 * PageInfo pi = PageInfo.getInstance(pageNo,
	 * systemSettingBo.getIntValue("DEFAULT_PAGE_SIZE"), total);
	 * 
	 * if (StringUtil.hasText(qo.getName()) &&
	 * !StringUtil.hasText(qo.getTeacherName()) &&
	 * !StringUtil.hasText(qo.getStart())) { result = courseDao.findCourse(hql,
	 * pi, Param.getCommonParam("currTime", currTime, Type.STRING),
	 * Param.getDefaultVarcharParamForLike("name", qo.getName())); } else if
	 * (!StringUtil.hasText(qo.getName()) &&
	 * StringUtil.hasText(qo.getTeacherName()) &&
	 * !StringUtil.hasText(qo.getStart())) { result = courseDao.findCourse( hql,
	 * pi, Param.getCommonParam("currTime", currTime, Type.STRING),
	 * Param.getDefaultVarcharParamForLike("teacherName", qo.getTeacherName()));
	 * } else if (StringUtil.hasText(qo.getName()) &&
	 * StringUtil.hasText(qo.getTeacherName()) &&
	 * !StringUtil.hasText(qo.getStart())) { result = courseDao.findCourse( hql,
	 * pi, Param.getCommonParam("currTime", currTime, Type.STRING),
	 * Param.getDefaultVarcharParamForLike("name", qo.getName()),
	 * Param.getDefaultVarcharParamForLike("teacherName", qo.getTeacherName()));
	 * } else if (StringUtil.hasText(qo.getName()) &&
	 * StringUtil.hasText(qo.getTeacherName()) &&
	 * StringUtil.hasText(qo.getStart()) && StringUtil.hasText(qo.getEnd())) {
	 * result = courseDao.findCourse( hql, pi, Param.getCommonParam("currTime",
	 * currTime, Type.STRING), Param.getDefaultVarcharParamForLike("name",
	 * qo.getName()), Param.getDefaultVarcharParamForLike("teacherName",
	 * qo.getTeacherName()), Param.getCommonParam("start", qo.getStart(),
	 * Type.STRING), Param.getCommonParam("end", qo.getEnd(), Type.STRING)); }
	 * else if (StringUtil.hasText(qo.getName()) &&
	 * StringUtil.hasText(qo.getTeacherName()) &&
	 * StringUtil.hasText(qo.getStart()) && !StringUtil.hasText(qo.getEnd())) {
	 * //TODO 不确定因素 result = courseDao.findCourse( hql, pi,
	 * Param.getCommonParam("currTime", currTime, Type.STRING),
	 * Param.getDefaultVarcharParamForLike("name", qo.getName()),
	 * Param.getDefaultVarcharParamForLike("teacherName", qo.getTeacherName()),
	 * Param.getCommonParam("start", qo.getStart(), Type.STRING),
	 * Param.getCommonParam("end", currTime, Type.STRING)); } else if
	 * (!StringUtil.hasText(qo.getName()) &&
	 * !StringUtil.hasText(qo.getTeacherName()) &&
	 * StringUtil.hasText(qo.getStart()) && !StringUtil.hasText(qo.getEnd())) {
	 * result = courseDao.findCourse( hql, pi, Param.getCommonParam("currTime",
	 * currTime, Type.STRING), Param.getCommonParam("start", qo.getStart(),
	 * Type.STRING), Param.getCommonParam("end", currTime, Type.STRING)); } else
	 * if (!StringUtil.hasText(qo.getName()) &&
	 * !StringUtil.hasText(qo.getTeacherName()) &&
	 * StringUtil.hasText(qo.getStart()) && StringUtil.hasText(qo.getEnd())) {
	 * result = courseDao.findCourse( hql, pi, Param.getCommonParam("currTime",
	 * currTime, Type.STRING), Param.getCommonParam("start", qo.getStart(),
	 * Type.STRING), Param.getCommonParam("end", qo.getEnd(), Type.STRING)); }
	 * else { result = courseDao.findCourse(hql, pi,
	 * Param.getCommonParam("currTime", currTime, Type.STRING)); }
	 * 
	 * if (CollectionUtil.isEmpty(result)) { return new
	 * DtoResultWithPageInfo<CourseDto>( new ArrayList<CourseDto>(), null); }
	 * 
	 * List<CourseDto> dtoResult = new ArrayList<CourseDto>(result.size()); for
	 * (Course entity : result) { CourseDto courseDto = new CourseDto();
	 * BeanPropertyUtil.copy(courseDto, entity); dtoResult.add(courseDto); }
	 * return new DtoResultWithPageInfo<CourseDto>(dtoResult, pi); }
	 */
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.edu.tsinghua.cic.ccss.bo.CourseBo#export(cn.edu.tsinghua.cic.ccss.
	 * qo.CourseQo)
	 */
	@Override
	@Transactional
	public List<CourseDto4Export> export(CourseQo qo) {
		QueryInfo qi = QueryObjectHelper.buildQueryInfo(qo);
		List<Course> result = hibernateDao.findEntities(qi);
		if (CollectionUtil.isEmpty(result)) {
			return new ArrayList<CourseDto4Export>();
		}

		List<CourseDto4Export> dtoResult = new ArrayList<CourseDto4Export>(
				result.size());
		for (Course entity : result) {
			CourseDto4Export courseDto = new CourseDto4Export();
			BeanPropertyUtil.copy(courseDto, entity);
			dtoResult.add(courseDto);
		}
		return dtoResult;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.edu.tsinghua.cic.ccss.bo.CourseBo#doDelete(java.lang.Long)
	 */
	@Override
	@Transactional
	public void doDelete(Long id) {
		Course entity = hibernateDao.load(Course.class, id);
		hibernateDao.delete(entity);
		String hql = "DELETE FROM CourseSelection where courseId=:id";
		hibernateDao.executeUpdate(hql,
				Param.getCommonParam("id", id, Type.LONG));
		hql = "DELETE FROM CourseCanceled where courseId=:id";
		hibernateDao.executeUpdate(hql,
				Param.getCommonParam("id", id, Type.LONG));
		hql = "DELETE FROM Courseware where courseId=:id";
		hibernateDao.executeUpdate(hql,
				Param.getCommonParam("id", id, Type.LONG));
	}

	@Transactional
	public void doDeleteCourseware(long courseId) {
		String hql = "DELETE FROM Courseware where courseId=:id";
		hibernateDao.executeUpdate(hql,
				Param.getCommonParam("id", courseId, Type.LONG));
	}

	// 计算课程号
	private synchronized String getCourseNum() {
		String dateStr = DateUtil.convertDateToString(new Date(), "yyyyMMdd");

		String hql = "SELECT max(num) FROM Course WHERE num like :num";
		String result = hibernateDao.findCommonObject(hql, Param
				.getVarcharParamForLike("num", dateStr, true, MatchType.START));
		if (!StringUtil.hasText(result)) {
			return dateStr + "001";
		}
		return "" + (NumberUtil.parseNumber(result, Long.class) + 1);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.edu.tsinghua.cic.ccss.bo.CourseBo#querySendMailToCadreDto()
	 */
	@Override
	@Transactional
	public List<SendMessageToCadreDto> querySendMailToCadreDto() {
		List<SendMessageToCadreDto> resultList = new ArrayList<SendMessageToCadreDto>();

		String hql = "FROM Course WHERE endTimeChoose<=to_date(:currentTime,'yyyy/MM/dd HH24:MI') AND teachTime>=to_date(:currentTime,'yyyy/MM/dd HH24:MI') AND sendEmailFlag='0'";
		Date currDate = DateUtil.currentTime();
		List<Course> courseList = hibernateDao.findEntities(hql, false, Param
				.getCommonParam("currentTime", DateUtil.convertDateToString(
						currDate, "yyyy/MM/dd HH:mm"), Type.STRING));
		LogUtil.info(log, "满足条件即将发送邮件的课程数目是================ :%d",
				courseList.size());
		if (CollectionUtil.isEmpty(courseList)) {
			return new ArrayList<SendMessageToCadreDto>();
		}

		String getCadreIdHql = "SELECT cadreId FROM CourseSelection WHERE courseId=:courseId AND deletedCardNum='0'";
		String getCadreEmailHql = "SELECT email FROM Cadre WHERE id in (:cadreIds) AND email IS NOT NULL";
		for (Course course : courseList) {
			Long courseId = course.getId();
			Object[] cadreIds = hibernateDao.findObjectArray(getCadreIdHql,
					Param.getCommonParam("courseId", courseId, Type.LONG));
			LogUtil.info(log, "满足条件即将收到邮件的人数是================ :%d",
					cadreIds.length);
			if (ArrayUtil.isEmpty(cadreIds)) {
				continue;
			}

			Object[] cadreEmails = hibernateDao.findObjectArray(
					getCadreEmailHql,
					Param.getCommonParam("cadreIds", cadreIds, Type.ARRAY));
			if (ArrayUtil.isEmpty(cadreEmails)) {
				continue;
			}

			for (int i = 0; i < cadreEmails.length; i++) {
				cadreEmails[i] = TripletsDESUtil.decrypt(systemSettingBo
						.getStringValue("CURRENT_TRIPLETS_DES_KEY"),
						(String) cadreEmails[i]);
			}

			// 排重
			cadreEmails = ArrayUtil.getWithoutDuplicatesArray(cadreEmails);

			String allEmail = StringUtils
					.arrayToCommaDelimitedString(cadreEmails);
			SendMessageToCadreDto dto = new SendMessageToCadreDto();
			BeanPropertyUtil.copy(dto, course);
			dto.setCurrentTime(DateUtil.convertDateToString(new Date(),
					"yyyy年MM月dd日"));
			dto.setTeachTimeStr(DateUtil.convertDateToString(
					dto.getTeachTime(), "yyyy年MM月dd日 HH时mm分"));
			dto.setCadreEmails(allEmail);
			resultList.add(dto);
		}

		Course[] courseArr = new Course[courseList.size()];
		int i = 0;
		for (Course course : courseList) {
			course.setSendEmailFlag("1");
			courseArr[i] = course;
			i++;
		}
		hibernateDao.update(courseArr);

		return resultList;
	}

	@Override
	@Transactional
	public List<SendMessageToCadreDto> querySendShortMessageToCadreDto() {
		List<SendMessageToCadreDto> resultList = new ArrayList<SendMessageToCadreDto>();

		Date curDate = DateUtil.currentTime();
		Date nextCurDate = DateUtil.calculateDate(curDate, 1,
				Calendar.DAY_OF_MONTH);
		String hql = "FROM Course WHERE teachTime<=to_date(:nextCurDate,'yyyy/MM/dd HH24:MI') AND teachTime>=to_date(:curDate,'yyyy/MM/dd HH24:MI') AND sendMessageFlag='0'";
		List<Course> courseList = hibernateDao.findEntities(hql, false, Param
				.getCommonParam("nextCurDate", DateUtil.convertDateToString(
						nextCurDate, "yyyy/MM/dd HH:mm"), Type.STRING), Param
				.getCommonParam("curDate", DateUtil.convertDateToString(
						curDate, "yyyy/MM/dd HH:mm"), Type.STRING));
		LogUtil.info(log, "满足条件即将发送短信的课程数目是============== :%d",
				courseList.size());
		if (CollectionUtil.isEmpty(courseList)) {
			return new ArrayList<SendMessageToCadreDto>();
		}

		String getCadreIdHql = "SELECT cadreId FROM CourseSelection WHERE courseId=:courseId AND deletedCardNum='0'";
		String getCadreMobileNumHql = "SELECT mobileNum FROM Cadre WHERE id in (:cadreIds) AND mobileNum IS NOT NULL";
		for (Course course : courseList) {
			Long courseId = course.getId();
			Object[] cadreIds = hibernateDao.findObjectArray(getCadreIdHql,
					Param.getCommonParam("courseId", courseId, Type.LONG));
			LogUtil.info(log, "满足条件即将收到短信的人数是================ :%d",
					cadreIds.length);
			if (ArrayUtil.isEmpty(cadreIds)) {
				continue;
			}

			Object[] cadreMobileNums = hibernateDao.findObjectArray(
					getCadreMobileNumHql,
					Param.getCommonParam("cadreIds", cadreIds, Type.ARRAY));
			LogUtil.info(log, "满足条件即将收到短信的手机号码数是================ :%d",
					cadreMobileNums.length);
			if (ArrayUtil.isEmpty(cadreMobileNums)) {
				continue;
			}
			for (int i = 0; i < cadreMobileNums.length; i++) {
				cadreMobileNums[i] = TripletsDESUtil.decrypt(systemSettingBo
						.getStringValue("CURRENT_TRIPLETS_DES_KEY"),
						(String) cadreMobileNums[i]);
			}

			// 排重
			cadreMobileNums = ArrayUtil
					.getWithoutDuplicatesArray(cadreMobileNums);

			String allNums = StringUtils
					.arrayToCommaDelimitedString(cadreMobileNums);
			// allNums = allNums.substring(0, allNums.length() - 1);
			SendMessageToCadreDto dto = new SendMessageToCadreDto();
			BeanPropertyUtil.copy(dto, course);
			dto.setCadreMobileNums(allNums);
			dto.setTeachTimeStr(DateUtil.convertDateToString(
					dto.getTeachTime(), "yyyy年MM月dd日HH时mm分"));
			resultList.add(dto);
		}

		Course[] courseArr = new Course[courseList.size()];
		int i = 0;
		for (Course course : courseList) {
			course.setSendMessageFlag("1");
			courseArr[i] = course;
			i++;
		}
		hibernateDao.update(courseArr);

		return resultList;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.edu.tsinghua.cic.ccss.bo.CourseBo#getMailMessageToCadre(java.lang.
	 * Long)
	 */
	@Override
	@Transactional
	public String getMailMessageToCadre(Long courseId) throws AddressException {
		Course course = hibernateDao.load(Course.class, courseId);
		SendMessageToCadreDto dto = new SendMessageToCadreDto();
		BeanPropertyUtil.copy(dto, course);
		dto.setCurrentTime(DateUtil.convertDateToString(new Date(),
				"yyyy年MM月dd日"));
		dto.setTeachTimeStr(DateUtil.convertDateToString(dto.getTeachTime(),
				"yyyy年MM月dd日HH时mm分"));

		Map<String, SendMessageToCadreDto> data = new HashMap<String, SendMessageToCadreDto>();
		data.put("dto", dto);
		return freeMarkerBean.getTemplateContent("to_students_email.ftl", data);
	}

	@Override
	@Transactional
	public String getShortMessageToCadre(Long courseId) {
		Course course = hibernateDao.load(Course.class, courseId);
		SendMessageToCadreDto dto = new SendMessageToCadreDto();
		BeanPropertyUtil.copy(dto, course);
		dto.setTeachTimeStr(DateUtil.convertDateToString(dto.getTeachTime(),
				"yyyy年MM月dd日 HH时mm分"));

		Map<String, SendMessageToCadreDto> data = new HashMap<String, SendMessageToCadreDto>();
		data.put("dto", dto);
		return freeMarkerBean.getTemplateContent("to_students_sms.ftl", data);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.edu.tsinghua.cic.ccss.bo.CourseBo#sendMail(java.lang.Long,
	 * java.lang.String)
	 */
	@Override
	@Transactional
	public void sendMail(Long courseId, String msg) {
		Course course = hibernateDao.load(Course.class, courseId);
		String getCadreIdHql = "SELECT cadreId FROM CourseSelection WHERE courseId=:courseId AND deletedCardNum='0'";
		String getCadreEmailHql = "SELECT email FROM Cadre WHERE id in (:cadreIds) AND email IS NOT NULL";
		Object[] cadreIds = hibernateDao.findObjectArray(getCadreIdHql,
				Param.getCommonParam("courseId", courseId, Type.LONG));

		Object[] cadreEmails = null;
		if (ArrayUtil.isEmpty(cadreIds)) {
			LogUtil.warn(log, "发送开课通知邮件时未找到选择课程ID为%d课程的干部数据", courseId);
			return;
		} else {
			cadreEmails = hibernateDao.findObjectArray(getCadreEmailHql,
					Param.getCommonParam("cadreIds", cadreIds, Type.ARRAY));
		}
		if (ArrayUtil.isEmpty(cadreEmails)) {
			LogUtil.warn(log, "发送开课通知邮件时未找到选择课程ID为%d课程的干部Email地址", courseId);
			return;
		}
		for (int i = 0; i < cadreEmails.length; i++) {
			cadreEmails[i] = TripletsDESUtil.decrypt(
					systemSettingBo.getStringValue("CURRENT_TRIPLETS_DES_KEY"),
					(String) cadreEmails[i]);
		}

		// 排重
		cadreEmails = ArrayUtil.getWithoutDuplicatesArray(cadreEmails);

		String allEmail = StringUtils.arrayToCommaDelimitedString(cadreEmails);
		SendMessageToCadreDto dto = new SendMessageToCadreDto();
		BeanPropertyUtil.copy(dto, course);
		dto.setCadreEmails(allEmail);

		Email email = new HtmlEmail();
		email.setCharset("UTF-8");
		email.setHostName(systemSettingBo.getStringValue("EMAIL_HOST_NAME"));
		email.setAuthenticator(new DefaultAuthenticator(systemSettingBo
				.getStringValue("EMAIL_USERNAME"), systemSettingBo
				.getStringValue("EMAIL_PASSWORD")));
		try {
			email.setFrom(systemSettingBo.getStringValue("EMAIL_FROM"));
			email.setSubject(dto.getName() + "-开课通知");
			InternetAddress[] adds = InternetAddress
					.parse(dto.getCadreEmails());
			email.setTo(Arrays.asList(adds));
			Map<String, SendMessageToCadreDto> data = new HashMap<String, SendMessageToCadreDto>();
			data.put("dto", dto);
			email.setMsg(msg);

			email.send();
		} catch (EmailException e) {
			LogUtil.error(log, "邮件发送异常：%s", e.getMessage());
		} catch (AddressException e) {
			LogUtil.error(log, "邮件地址异常：%s", e.getMessage());
		}
	}
	
	@Override
	@Transactional
	public String getCheckinShortMsgToCadre(Long courseId) throws AddressException{
		Course course = hibernateDao.load(Course.class, courseId);
		SendMessageToCadreDto dto = new SendMessageToCadreDto();
		BeanPropertyUtil.copy(dto, course);

		Map<String, SendMessageToCadreDto> data = new HashMap<String, SendMessageToCadreDto>();
		data.put("dto", dto);
		return freeMarkerBean.getTemplateContent("to_students_checkin_sms.ftl", data);
	}
	
	@Override
	@Transactional
	public void handleReceiptedShortMsg(String phoneNum, String content) {
		/*if(!StringUtil.hasText(phoneNum) || !StringUtil.hasText(content)){
			return ;
		}*/
		
		LogUtil.info(log, "于%s接收到的手机号码为："+ phoneNum +"，短信内容：" + content , 
				DateUtil.convertDateToString(new Date()));
		String key = systemSettingBo.getStringValue("CURRENT_TRIPLETS_DES_KEY");
		
		String hql_cadreId = "select id from Cadre where mobileNum = :phoneNumEncrypted";
		String phoneNumEncrypted = TripletsDESUtil.encrypt(key, phoneNum);
		Long cadreId = hibernateDao.findCommonObject(hql_cadreId, 
				Param.getCommonParam("phoneNumEncrypted", phoneNumEncrypted, Type.STRING));
		if(cadreId == null){
			LogUtil.info(log, "于%s考勤短信接收非法手机号、工作证号，处理返回", 
					DateUtil.convertDateToString(new Date()));
			return ;
		}
//		String cadreNum = TripletsDESUtil.decrypt(key, cadre[1].toString());
		// extract the coursename and A/B from the content . 
		String currTime = DateUtil.convertDateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
		Date receiptTime = DateUtil.convertStringToDate(currTime);
		int flag = org.apache.commons.lang3.StringUtils.lastIndexOf(content, "A");
		String result=null;
		if(flag == -1){
			result = "B";
		} else {
			result = "A";
		}
		String courseName = org.apache.commons.lang3.StringUtils.
				substringBetween(content, "#干部选学#", result);
		// 若回复格式符合模板要求，系统将自动处理短信。
		if(courseName != null && !"".equals(courseName)){
			String hql_courseId = "select courseId from Course where name like :courseName";
			Long courseId = hibernateDao.findCommonObject(hql_courseId,
					Param.getDefaultVarcharParamForLike("courseName", courseName));
			if(courseId !=null){
				//TODO 缺少一个状态设置
				String hql_courseSelection = "update CourseSelection set resultOfShortMsgSign = :result " +
						"where courseId = :courseId and cadreId = :cadreId";
				hibernateDao.executeUpdate(hql_courseSelection, 
						Param.getCommonParam("result", result, Type.STRING),
						Param.getCommonParam("courseId", courseId, Type.LONG),
						Param.getCommonParam("cadreId", cadreId, Type.LONG));
				LogUtil.info(log, "于%s完成系统自动处理考勤结果："+result, 
						DateUtil.convertDateToString(new Date()));
			}
		}
		// 保存考勤回复短信
		MsgResultOfChekIn msgResultOfChekIn = new MsgResultOfChekIn();
		msgResultOfChekIn.setContent(content);
		msgResultOfChekIn.setReceiptTime(receiptTime);
		msgResultOfChekIn.setCadreId(cadreId);
		hibernateDao.save(msgResultOfChekIn);
		LogUtil.info(log, "于%s完成考勤短信信息保存操作", 
				DateUtil.convertDateToString(new Date()));
	}
	
	// 发送考勤短信！
	@Override
	@Transactional
	public void sendCheckInShortMsg(long courseId, Long[] cadreIds,String msg) {
		Course course = hibernateDao.load(Course.class, courseId);
		String getCadreMobileNumHql = "SELECT mobileNum FROM Cadre WHERE id in (:cadreIds) AND mobileNum IS NOT NULL";
		Object[] mobileNums = null;
		if (ArrayUtil.isEmpty(cadreIds)) {
			LogUtil.warn(log, "发送考勤短信时未找到选择课程ID为%d课程的干部数据", courseId);
			return;
		} else {
			mobileNums = hibernateDao.findObjectArray(getCadreMobileNumHql,
					Param.getCommonParam("cadreIds", cadreIds, Type.ARRAY));
		}
		if (ArrayUtil.isEmpty(mobileNums)) {
			LogUtil.warn(log, "发送考勤短信时未找到选择课程ID为%d课程的干部手机号", courseId);
			return;
		}
		for (int i = 0; i < mobileNums.length; i++) {
			mobileNums[i] = TripletsDESUtil.decrypt(
					systemSettingBo.getStringValue("CURRENT_TRIPLETS_DES_KEY"),
					(String) mobileNums[i]);
		}
		
		// 排重
				mobileNums = ArrayUtil.getWithoutDuplicatesArray(mobileNums);

				String allMobileNums = StringUtils
						.arrayToCommaDelimitedString(mobileNums);
				SendMessageToCadreDto dto = new SendMessageToCadreDto();
				BeanPropertyUtil.copy(dto, course);
				dto.setCadreMobileNums(allMobileNums);

				String message = "";
				Map<String, SendMessageToCadreDto> data = new HashMap<String, SendMessageToCadreDto>();
				data.put("dto", dto);
				/*String msg = freeMarkerBean.getTemplateContent(
						"to_students_checkin_sms.ftl", data);*/
				SmsClient.setServiceUrl(PropertiesFileReader.getValue("forten-system",
						"sms.url"));
				int code = SmsClient.sendMass(
						PropertiesFileReader.getValue("forten-system", "sms.appId"),
						PropertiesFileReader.getValue("forten-system", "sms.appKey"),
						dto.getCadreMobileNums(), msg);
				switch (code) {
				case 0:
					message = "SMS[0]:发送开课通知短信成功，success";
					break;
				case 10:
					message = "SMS[10]:调用参数错误，invokation param error";
					break;
				case 20:
					message = "SMS[20]:应用认证失败， auth error";
					break;
				case 900:
					message = "SMS[900]:数据库访问错误，DB access error";
					break;
				case 901:
					message = "SMS[901]:没有设置服务器URL地址，not setting server url address";
					break;
				case 902:
					message = "SMS[902]:连接服务器错误，server connection exception";
					break;
				default:
					break;
				}

				LogUtil.debug(log, message);
	}

	@Override
	@Transactional
	public void sendShortMessage(Long courseId, String msg) {
		Course course = hibernateDao.load(Course.class, courseId);
		String getCadreIdHql = "SELECT cadreId FROM CourseSelection WHERE courseId=:courseId AND deletedCardNum='0'";
		String getCadreMobileNumHql = "SELECT mobileNum FROM Cadre WHERE id in (:cadreIds) AND mobileNum IS NOT NULL";
		Object[] cadreIds = hibernateDao.findObjectArray(getCadreIdHql,
				Param.getCommonParam("courseId", courseId, Type.LONG));

		Object[] mobileNums = null;
		if (ArrayUtil.isEmpty(cadreIds)) {
			LogUtil.warn(log, "发送开课通知短信时未找到选择课程ID为%d课程的干部数据", courseId);
			return;
		} else {
			mobileNums = hibernateDao.findObjectArray(getCadreMobileNumHql,
					Param.getCommonParam("cadreIds", cadreIds, Type.ARRAY));
		}
		if (ArrayUtil.isEmpty(mobileNums)) {
			LogUtil.warn(log, "发送开课通知短信时未找到选择课程ID为%d课程的干部手机号", courseId);
			return;
		}
		for (int i = 0; i < mobileNums.length; i++) {
			mobileNums[i] = TripletsDESUtil.decrypt(
					systemSettingBo.getStringValue("CURRENT_TRIPLETS_DES_KEY"),
					(String) mobileNums[i]);
		}

		// 排重
		mobileNums = ArrayUtil.getWithoutDuplicatesArray(mobileNums);

		String allMobileNums = StringUtils
				.arrayToCommaDelimitedString(mobileNums);
		SendMessageToCadreDto dto = new SendMessageToCadreDto();
		BeanPropertyUtil.copy(dto, course);
		dto.setCadreMobileNums(allMobileNums);

		String message = "";
		Map<String, SendMessageToCadreDto> data = new HashMap<String, SendMessageToCadreDto>();
		data.put("dto", dto);
		SmsClient.setServiceUrl(PropertiesFileReader.getValue("forten-system",
				"sms.url"));
		int code = SmsClient.sendMass(
				PropertiesFileReader.getValue("forten-system", "sms.appId"),
				PropertiesFileReader.getValue("forten-system", "sms.appKey"),
				dto.getCadreMobileNums(), msg);
		switch (code) {
		case 0:
			message = "SMS[0]:发送开课通知短信成功，success";
			break;
		case 10:
			message = "SMS[10]:调用参数错误，invokation param error";
			break;
		case 20:
			message = "SMS[20]:应用认证失败， auth error";
			break;
		case 900:
			message = "SMS[900]:数据库访问错误，DB access error";
			break;
		case 901:
			message = "SMS[901]:没有设置服务器URL地址，not setting server url address";
			break;
		case 902:
			message = "SMS[902]:连接服务器错误，server connection exception";
			break;
		default:
			break;
		}

		LogUtil.debug(log, message);
	}

	/*
	 * @Override
	 * 
	 * @Transactional public DtoResultWithPageInfo<CourseDto>
	 * queryCourseDtoPage4Selection( CourseSelectAdminQo qo, int page, String
	 * fieldName, boolean isAsc) { QueryInfo qi =
	 * QueryObjectHelper.buildQueryInfo(qo);
	 * qi.setSelect(Select.getCountSelect("id")); Long totalEntities =
	 * hibernateDao.getCount(qi); if (totalEntities == 0) { return new
	 * DtoResultWithPageInfo<CourseDto>( new ArrayList<CourseDto>(), null); }
	 * 
	 * PageInfo pi = PageInfo .getInstance(page,
	 * systemSettingBo.getIntValue("DEFAULT_PAGE_SIZE"), totalEntities);
	 * if(isAsc){ qi.setOrderby(OrderBy.getOrderBy(Order.asc(fieldName))); }
	 * else { qi.setOrderby(OrderBy.getOrderBy(Order.desc(fieldName))); }
	 * qi.setFirstResult(pi.getFirstResultNum());
	 * qi.setMaxResult(pi.getPageSize()); qi.setPage(true); qi.setSelect(null);
	 * qi.setUseCache(true);
	 * 
	 * List<Course> result = hibernateDao.findEntities(qi); List<CourseDto>
	 * dtoResult = new ArrayList<CourseDto>(result.size()); for (Course entity :
	 * result) { CourseDto courseDto = new CourseDto();
	 * BeanPropertyUtil.copy(courseDto, entity); dtoResult.add(courseDto); }
	 * return new DtoResultWithPageInfo<CourseDto>(dtoResult, pi); }
	 */

	/*
	 * 
	 * @Override
	 * 
	 * @Transactional public DtoResultWithPageInfo<CourseDto>
	 * queryCourseDtoPage4Selection( CourseSelectCadreQo qo, int page, String
	 * fieldName, boolean isAsc) { QueryInfo qi =
	 * QueryObjectHelper.buildQueryInfo(qo);
	 * qi.setSelect(Select.getCountSelect("id")); Long totalEntities =
	 * hibernateDao.getCount(qi); if (totalEntities == 0) { return new
	 * DtoResultWithPageInfo<CourseDto>( new ArrayList<CourseDto>(), null); }
	 * 
	 * PageInfo pi = PageInfo .getInstance(page,
	 * systemSettingBo.getIntValue("DEFAULT_PAGE_SIZE"), totalEntities);
	 * if(isAsc){ qi.setOrderby(OrderBy.getOrderBy(Order.asc(fieldName))); }
	 * else { qi.setOrderby(OrderBy.getOrderBy(Order.desc(fieldName))); }
	 * qi.setFirstResult(pi.getFirstResultNum());
	 * qi.setMaxResult(pi.getPageSize()); qi.setPage(true); qi.setSelect(null);
	 * qi.setUseCache(true);
	 * 
	 * List<Course> result = hibernateDao.findEntities(qi); List<CourseDto>
	 * dtoResult = new ArrayList<CourseDto>(result.size()); for (Course entity :
	 * result) { CourseDto courseDto = new CourseDto();
	 * BeanPropertyUtil.copy(courseDto, entity); dtoResult.add(courseDto); }
	 * return new DtoResultWithPageInfo<CourseDto>(dtoResult, pi); }
	 */

	@Override
	@Transactional
	public <Q extends QueryObject> DtoResultWithPageInfo<CourseDto> queryCourseDtoPage(
			Q qo, int page, String fieldName, boolean isAsc) {
		QueryInfo qi = QueryObjectHelper.buildQueryInfo(qo);
		qi.setSelect(Select.getCountSelect("id"));
		Long totalEntities = hibernateDao.getCount(qi);
		if (totalEntities == 0) {
			return new DtoResultWithPageInfo<CourseDto>(
					new ArrayList<CourseDto>(), null);
		}

		PageInfo pi = PageInfo
				.getInstance(page,
						systemSettingBo.getIntValue("DEFAULT_PAGE_SIZE"),
						totalEntities);
		if (isAsc) {
			qi.setOrderby(OrderBy.getOrderBy(Order.asc(fieldName)));
		} else {
			qi.setOrderby(OrderBy.getOrderBy(Order.desc(fieldName)));
		}
		qi.setFirstResult(pi.getFirstResultNum());
		qi.setMaxResult(pi.getPageSize());
		qi.setPage(true);
		qi.setSelect(null);
		qi.setUseCache(true);

		List<Course> result = hibernateDao.findEntities(qi);
		List<CourseDto> dtoResult = new ArrayList<CourseDto>(result.size());

		for (Course entity : result) {
			String hql = "select count(id) from Courseware where courseId=:courseId";
			Param p = Param.getCommonParam("courseId", entity.getId(),
					Type.LONG);
			int wareQ = NumberUtil.convertNumberToTargetClass(
					hibernateDao.getCount(hql, p), Integer.class);
			CourseDto courseDto = new CourseDto();
			BeanPropertyUtil.copy(courseDto, entity);
			Date endTime = courseDto.getEndTimeChoose();
			Date currentTime = DateUtil.currentTime();
			if (currentTime.before(endTime)) {
				courseDto.setIsOvertime(0);
			} else {
				courseDto.setIsOvertime(1);
			}
			courseDto.setCoursewareQuantity(wareQ);
			dtoResult.add(courseDto);
		}
		return new DtoResultWithPageInfo<CourseDto>(dtoResult, pi);
	}

	@Override
	@Transactional
	public void doDeleteShortMsgOfCheckIn(Long[] ids) {
		String hql = "delete MsgResultOfChekIn where id = :id";
		for (Long id : ids) {
			hibernateDao.executeUpdate(hql, 
					Param.getCommonParam("id", id, Type.LONG));
		}
	}

	

}